Skip to content

ADFA-4857 | Add project-to-template plugin - #56

Merged
hal-eisen-adfa merged 3 commits into
mainfrom
ADFA-4857-templatizer-plugin
Jul 31, 2026
Merged

ADFA-4857 | Add project-to-template plugin#56
hal-eisen-adfa merged 3 commits into
mainfrom
ADFA-4857-templatizer-plugin

Conversation

@hal-eisen-adfa

Copy link
Copy Markdown
Contributor

Summary

Incorporates the standalone templatize-project plugin into the monorepo as project-to-template/, conforming to repo conventions and wired into the build + website-deploy pipelines.

The plugin adds a Project to Template sidebar item that converts the currently-open Android project into a Code On The Go .cgt template bundle (original untouched — it copies then tokenizes with Pebble ${{TOKEN}}s) and can install it straight into the New Project template picker via IdeTemplateService.

What changed on the way in

  • Full rename to org.appdevforall.projecttotemplate / "Project to Template".
  • Shared infra: uses repo-root ../libs/*.jar and ../gradlew — no bundled jars or wrapper.
  • Tooltip fix: getTooltipCategory() now returns the full plugin_org.appdevforall.projecttotemplate id, so the in-IDE tooltip renders real text instead of the literal n/a.
  • Security: sanitizes the user-typed template name before using it as a filesystem path.
  • Docs: Tier 3 offline help (assets/docs/index.html) + top-level website project-to-template-documentation.html.
  • New icon: solid project card → arrow → dashed template card (day/night PNGs + monochrome ic_plugin vector), replacing the 4-square grid glyph. Source SVGs + generator under icon-src/.
  • Text: normalized user-facing strings to "Code On The Go".
  • Wiring: README Examples row + update-libs.yml website MAP entry.

Verification

  • ../gradlew assemblePlugin and assemblePluginDebug both build clean.
  • Passed the plugin-review rubric (green-light; 6.1 min-only IDE version is the repo norm).
  • Device-verified on emulator end-to-end: installs, activates (survives restart), sidebar + 3-tier tooltip render (no n/a), and a real conversion of an open project (15 modified) produces a .cgt that installs via IdeTemplateService ([OK] Installed template).

🤖 Generated with Claude Code

… .cgt template)

Incorporates the standalone templatize-project plugin into the monorepo as
project-to-template, conforming to repo conventions and wired into the build
and website-deploy pipelines.

- Full rename to org.appdevforall.projecttotemplate / "Project to Template".
- Uses shared repo-root ../libs/*.jar and ../gradlew (no bundled copies).
- Fixes tooltip category to the full plugin.id (plugin_org.appdevforall.projecttotemplate)
  so the in-IDE tooltip renders real text instead of "n/a".
- Sanitizes the user-typed template name before using it as a filesystem path.
- Adds Tier 3 offline docs (assets/docs/index.html) + website documentation page.
- New icon: solid project card -> arrow -> dashed template card (day/night PNGs +
  monochrome ic_plugin vector), replacing the 4-square grid glyph. Source SVGs +
  generator under icon-src/.
- Normalizes user-facing text to "Code On The Go".
- Adds README Examples row and update-libs.yml website MAP entry.

Device-verified on emulator: installs, activates, sidebar + 3-tier tooltip render,
and a real conversion of an open project produces a .cgt that installs via
IdeTemplateService.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.

Tip: disable this comment in your organization's Code Review settings.

@jatezzz jatezzz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review

Reviewed against freshly-fetched origin/main. I did not build or device-test — taking the PR's "builds clean + emulator-verified end-to-end" at face value.

What's right

The repo conventions are all here, including the ones that usually get missed: tooltip category is the full "plugin_org.appdevforall.projecttotemplate" form (not a slug), TOOLTIP_TAG is a shared const wired to the NavigationItem, Tier 3 getTier3DocsAssetPath() + a real assets/docs/index.html (white bg / black text), repo-root ../libs/*.jar + ../gradlew with no bundled copies, Theme.Material3.DayNight + values-night/, AAR metadata checks disabled, permission strings are exact enum values, sanitizeTemplateName genuinely kills traversal, views nulled in onDestroyView, dry run against a disposable temp copy, and both README + update-libs.yml MAP wiring are present.

Summary of findings

Should fix before merge:

  1. Dark-mode status colors are hardcoded — the values-night variants are dead resources.
  2. Re-running with a different template name zips the previous run into the new .cgt.
  3. skipCleanup suppresses the personal-info warning too, including keystores.
  4. local.properties ships in the .cgt by default.

Worth fixing (device-level cost):

  1. The entire build/ tree is copied, then deleted.
  2. Log rendering is O(n^2) on the main thread.

Minor: install button can't be retried after a failed install; the "unit-testable" KDoc claim is contradicted by android.util.Base64 + unitTests.isReturnDefaultValues = true; UI strings hardcoded rather than in strings.xml; duplicate log lines; isIgnoredUnderRoot is redundant with the onEnter prune; compileSdk/targetSdk = 34 will collide with #54.

Details are in the inline comments.

Verdict

Approve once #1 and #2 are fixed — those two produce visibly wrong output. #3/#4 are judgment calls, but both cut against the plugin's purpose (shipping a template someone else installs), so worth folding in here. Everything else is follow-up material.

Comment thread project-to-template/src/main/res/layout/fragment_main.xml Outdated
Comment thread project-to-template/build.gradle.kts
@hal-eisen-adfa
hal-eisen-adfa requested a review from a team July 31, 2026 16:14
Fixes from jatezzz's review:

Should-fix (produce visibly wrong output):
- Dark-mode status colors: use ContextCompat.getColor(status_*_text)
  instead of hardcoded light hex, so values-night/ is no longer dead.
- Re-run isolation: wipe the whole output dir (not just dest/) before a
  real run, so a previous template name's tree isn't zipped into the new
  .cgt.
- skipCleanup no longer suppresses the personal-info warning: keystores
  are flagged (not silently shipped) when cleanup is skipped, and
  flagPersonalInfoFiles always runs.
- local.properties is now in COPY_IGNORE (always machine-specific), so it
  is never bundled.

Worth-fixing:
- build/ is skipped at copy time when cleaning up, instead of copied then
  deleted (hundreds of MB of I/O on device).
- Log rendering uses TextView.append() (O(1)/line) instead of rebuilding
  the whole string per line.

Minor:
- Install button re-enables after a failed install so it can be retried.
- Switch android.util.Base64 -> java.util.Base64 (minSdk 26) and add JVM
  unit tests for sanitizeTemplateName + a dry-run substitution path.
- Move user-facing UI strings into strings.xml.
- Remove duplicate per-file [OK] log lines (writePeb already logs).
- Drop redundant isIgnoredUnderRoot (onEnter prune + name filter cover it).

Verified: testDebugUnitTest + assemblePlugin green; a JVM harness runs the
real createTemplateBundle twice (Foo then Bar) and confirms no stale-tree /
local.properties / build/ / keystore leakage into the .cgt.
@hal-eisen-adfa

Copy link
Copy Markdown
Contributor Author

Thanks for the thorough review, @jatezzz — addressed everything in 2957e4e.

Should-fix

  1. Dark-mode colorsshowStatus now uses ContextCompat.getColor(…, R.color.status_error_text / status_success_text), so values-night/ is live.
  2. Re-run bundling — a real run now wipes the whole outputDir (not just dest/) before copying, so a prior name's tree can't be zipped in. .cgt files live in outputDir.parentFile, so previous bundles are preserved.
  3. skipCleanup suppressing warningsflagPersonalInfoFiles now always runs; when cleanup is skipped, keystores are flagged ([REVIEW] … remove it before distributing) instead of silently shipped.
  4. local.properties — added to COPY_IGNORE outright; google-services.json left flag-only as you suggested.

Worth-fixing
5. build/ — added to the copy-time skip when !skipCleanup, so it's never copied (was copy-then-delete).
6. O(n²) log — switched to logText.append("$line\n").

Minor

  • Install button re-enables after a failed install (retry without re-converting).
  • android.util.Base64java.util.Base64 (minSdk 26), and added JVM unit tests: sanitizeTemplateName (incl. traversal) + a dry-run substitution path. The dry-run pipeline touches no Android APIs, so it's safe under isReturnDefaultValues.
  • UI strings moved to strings.xml.
  • Removed the duplicate per-file [OK] lines (writePeb already logs) at the three sites.
  • Deleted isIgnoredUnderRoot — the onEnter prune + name !in ignore filter cover it.

Note (12) — left compileSdk/targetSdk = 34 as-is. #54 (SDK 36) is still open and owns the toolchain bump; whichever lands second rebases, as you noted.

VerificationtestDebugUnitTest + assemblePlugin green. Beyond the unit tests I ran the real (non-dry) createTemplateBundle twice via a JVM harness (Foo then Bar) and asserted the resulting .cgt contains no stale Foo/ subtree, no local.properties, no build/, and no .jks by default — and that skipCleanup retains and flags the keystore. All passed.

@hal-eisen-adfa

Copy link
Copy Markdown
Contributor Author

Device verification (emulator, Code On The Go)

Installed the debug .cgp via IDE preferences → Plugin Manager (uninstalled the prior build, installed the new one, restarted) and drove the full flow against a real "My Application" project that contains a release.keystore, release.properties, and a build/ dir.

.cgt contents confirmed by pulling each bundle off the device and inspecting with unzip.

…-plugin

# Conflicts:
#	.github/workflows/update-libs.yml
#	README.md
@hal-eisen-adfa
hal-eisen-adfa merged commit 3a18cc7 into main Jul 31, 2026
@hal-eisen-adfa
hal-eisen-adfa deleted the ADFA-4857-templatizer-plugin branch July 31, 2026 23:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants